package com.atme.micromall.member.service.impl;

import com.aliyuncs.exceptions.ClientException;
import com.atme.micromall.member.bean.Members;
import com.atme.micromall.member.bean.MembersExample;
import com.atme.micromall.member.dto.CommonResult;
import com.atme.micromall.member.dto.MemberParam;
import com.atme.micromall.member.mapper.CustomMembersMapper;
import com.atme.micromall.member.mapper.MembersMapper;
import com.atme.micromall.member.service.AsyncService;
import com.atme.micromall.member.service.MemberService;
import com.atme.micromall.member.service.ServicePointsFeignClient;
import com.atme.micromall.member.util.JwtUtils;
import com.atme.micromall.member.util.KafkaUtils;
import com.atme.micromall.member.util.UuidUtil;

import org.apache.commons.lang.StringUtils;
import com.alibaba.fastjson.JSON;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class MemberServiceImpl implements MemberService {


    @Autowired
    private MembersMapper membersMapper;

    @Autowired
    private CustomMembersMapper customMembersMapper;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private ServicePointsFeignClient servicePointsFeignClient;

    @Autowired
    private KafkaUtils kafkaUtils;

    @Autowired
    private AsyncService asyncService;

    @Value("${redis.database}")  //mall
    private String REDIS_DATABASE;
    @Value("${redis.expire.common}") //86400 # 24小时
    private Long REDIS_EXPIRE;
    @Value("${redis.key.admin}")  //  用户名 'ums:admin'
    private String REDIS_KEY_ADMIN;
    @Value("${redis.key.resourceList}")  //  用户ID 'ums:resourceList' phoneNumber
    private String REDIS_KEY_RESOURCE_LIST;
    @Value("${redis.key.phoneNumber}")  //  用户手机号 'phoneNumber'
    private String REDIS_KEY_PHONE_NUMBER;


    /**
     * 生成短信验证码并存入redis保存10发送短信  存储格式：key(mall:phoneNumber:手机号)   value(yzm)
     * @param phoneNumber
     */
    @Override
    public void setSms(String phoneNumber) throws ClientException {

        //同一用户一小时内只能发5次，超过5次要等待1小时
/*        String smsTimeKey = phoneNumber+"time";
        Object time=redisTemplate.opsForValue().get(smsTimeKey);
        if (time!=null&&Integer.parseInt(time.toString())>5){
            redisTemplate.expire(smsTimeKey,60,TimeUnit.MINUTES);
            return;
        }else if (time!=null&&Integer.parseInt(time.toString())<5){
            redisTemplate.opsForValue().increment(smsTimeKey,1);
        }else{
            redisTemplate.opsForValue().set(smsTimeKey, 1, 60, TimeUnit.MINUTES);
        }*/

        String yzm = getYzm();

        //封装发送参数
        Map<String,String> map=new HashMap<>();
        map.put("phone",phoneNumber);
        map.put("yzm",yzm);
        String json=JSON.toJSONString(map);

        //将参数发送给kafka
        kafkaUtils.sendMessage("phoneTopic",json);

        String key = REDIS_DATABASE + ":" + REDIS_KEY_PHONE_NUMBER + ":" + phoneNumber;
        redisTemplate.opsForValue().set(key, yzm, 600, TimeUnit.SECONDS);
    }


    /**
     *登录
     * @param userNameOrPhoneNumber
     * @param password
     * @param phoneNumber
     * @param smsCode
     * @param login  用户名/手机号+密码登录：login=1；手机验证码登录：login=2（此处未注册时自动注册）
     * @return
     */
    @Override
    public String login(String userNameOrPhoneNumber, String password, String phoneNumber, String smsCode, Integer login) {

        if(login==1){
            MembersExample MembersExample = new MembersExample();
            MembersExample.Criteria criteria = MembersExample.createCriteria();
            if (StringUtils.isNotBlank(userNameOrPhoneNumber)) {
                criteria.andUserNameEqualTo(userNameOrPhoneNumber);
            }
            if (StringUtils.isNotBlank(password)) {
                criteria.andPasswordEqualTo(password);
            }
            List<Members> members1=membersMapper.selectByExample(MembersExample);


            MembersExample MembersExample2 = new MembersExample();
            MembersExample.Criteria criteria2 = MembersExample2.createCriteria();
            if (StringUtils.isNotBlank(userNameOrPhoneNumber)) {
                criteria2.andPhoneNumberEqualTo(userNameOrPhoneNumber);
            }
            if (StringUtils.isNotBlank(password)) {
                criteria2.andPasswordEqualTo(password);
            }
            List<Members> members2=membersMapper.selectByExample(MembersExample);

            if (members1.size()>0||members2.size()>0){
                return JwtUtils.createToken(phoneNumber,userNameOrPhoneNumber);  //返回成功
            }


        }else if(login==2){
            MembersExample MembersExample = new MembersExample();
            MembersExample.Criteria criteria = MembersExample.createCriteria();
            if (StringUtils.isNotBlank(phoneNumber)) {
                criteria.andPhoneNumberEqualTo(phoneNumber);
            }
            List<Members> members=membersMapper.selectByExample(MembersExample);
            if (members.size()==0){
                int count=create(phoneNumber,smsCode);
                if (count>0){
                    return JwtUtils.createToken(phoneNumber,userNameOrPhoneNumber);  //返回成功
                }
            }

            String key = REDIS_DATABASE + ":" + REDIS_KEY_PHONE_NUMBER + ":" + phoneNumber;
            Object value = redisTemplate.opsForValue().get(key);
            if(smsCode.equals(value)){
                return JwtUtils.createToken(phoneNumber,userNameOrPhoneNumber);//返回成功
            }
        }


        return null; //shibai
    }

    /**
     * 修改会员信息
     * @param id
     * @param memberParam
     * @return
     */
    @Override
    public int update(Integer id, MemberParam memberParam) {
        //判断用户名是否重复
        if (memberParam.getUserName()!=null){
            MembersExample MembersExample = new MembersExample();
            MembersExample.createCriteria().andUserNameEqualTo(memberParam.getUserName());
            List<Members> membersList=membersMapper.selectByExample(MembersExample);
            if(membersList.size()>0){
                return -1; //返回用户名重回提示
            }
        }
        Members members = new Members();
        BeanUtils.copyProperties(memberParam,members);
        members.setId(id);
        //将密码进行加密操作
        if (members.getPassword()!=null){
            String encodePassword = DigestUtils.md5DigestAsHex(members.getPassword().getBytes());
            members.setPassword(encodePassword);
        }
        int count=0;
        members.setUpdateTime(new Date());
        //count = customMembersMapper.update(members);  //此处需要删除redis的缓存
        MembersExample MembersExample2 = new MembersExample();
        MembersExample.Criteria criteria2 = MembersExample2.createCriteria();
        count = membersMapper.updateByPrimaryKeySelective(members);

        return count;
    }

    /**
     * 查询所有会员
     * @return
     */
    @Override
    public List<Members> getAllMembers() {
        MembersExample MembersExample = new MembersExample();
        MembersExample.Criteria criteria = MembersExample.createCriteria();
        List<Members> membersList=membersMapper.selectByExample(MembersExample);
        return membersList;
    }


    /**
     * 注册
     * @param phoneNumber
     * @param smsCode
     * @return
     */
    @Override
    public int create(String phoneNumber, String smsCode) {
        int count = 0;
        MembersExample MembersExample = new MembersExample();
        MembersExample.createCriteria().andPhoneNumberEqualTo(phoneNumber);
        List<Members> membersList = membersMapper.selectByExample(MembersExample);
        //判断手机号是否已注册
        if (membersList.size() > 0) {
            return -1;
        }
        String key = REDIS_DATABASE + ":" + REDIS_KEY_PHONE_NUMBER + ":" + phoneNumber;
        Object value = redisTemplate.opsForValue().get(key);
        if (smsCode.equals(value)) {
            Members members = new Members();
            members.setCreateTime(new Date());
            members.setPhoneNumber(phoneNumber);
            String userName = UuidUtil.getStringRandom();
            members.setUserName("mall" + userName);
            count = membersMapper.insert(members);
        }

        CommonResult commonResult =servicePointsFeignClient.create(1);
        long code=commonResult.getCode();
        System.out.println(code);

        return count;
    }

    /**
     * 测试redis锁
     * @param id
     * @param number
     * @return
     */
    @Override
    public int updatePoints(Integer id, Integer number) {

        CommonResult commonResult=servicePointsFeignClient.update(id,number);

        asyncService.updatePoints(id,number);
        asyncService.updatePoints(id,number);
        asyncService.updatePoints(id,number);
        if (commonResult.getCode()==200){
            return 1;
        }

        return 0;
    }

    /**
     * 查询会员信息
     * @param id
     * @return
     */
    @Override
    public Members getMemberById(Integer id) {

        Members members= membersMapper.selectByPrimaryKey(id);
        String key=REDIS_KEY_ADMIN+":"+members.getUserName();
        redisTemplate.opsForValue().set(key,members,200,TimeUnit.SECONDS);
        System.out.println(1);
        return members;
    }

    //验证码生产方法
    private String getYzm() {
        String yzm = "";
        for (int i = 0; i < 4; i++) {
            int int1 = new Random().nextInt(10);
            yzm += int1;
        }
        return yzm;
    }
}
